#include <string.h>
#include <sys/ioctl.h>

#include <hwicodec_common.h>
#ifdef DMALLOC
#include <imp/dmalloc.h>
#endif
int hwicodec_tlb(hwicodec_t *h, intptr_t vaddr, int size, int ch)
{
	struct init_buf_info ibinfo;

	ibinfo.clist = h->soc.cnpool.chn[ch].cnode.clist;
	ibinfo.buf_info.alloc_vaddr = vaddr;
	ibinfo.buf_info.alloc_size = size;
	ibinfo.buf_info.tlb_needed = true;

	if (ioctl(h->soc.fd, IOCTL_CHANNEL_BUF_INIT, &ibinfo) < 0) {
		hwicodec_log(h, C_LOG_ERROR, "tlb map vaddr:%p failed\n", vaddr);
		goto err_hwtlb;
	}

	return 0;

err_hwtlb:
	return -1;
}

int hwicodec_vb_tlb(hwicodec_t *h, hwicodec_plane_pool_t *ppool, hwicodec_plane_t *pplane,
		hwicodec_plane_size_t *psize, int cn)
{
	int i = 0;
	hwicodec_plane_info_t  e = {*pplane, *psize};
	for (i = 0; i < ppool->num; i++) {
		if (!memcmp(&ppool->elem[i], &e, sizeof(hwicodec_plane_info_t))) {
			break;
		}
	}
	if ( i == ppool->num) {
		if (hwicodec_tlb(h, pplane->yaddr, psize->ysize, cn) < 0) {
			hwicodec_log(h, C_LOG_ERROR, "tlb yaddr:%p, size:%d failed\n", pplane->yaddr, psize->ysize);
			goto err_hwicodec_fenc_y_tlb;
		}

		if (hwicodec_tlb(h, pplane->caddr, psize->csize, cn) < 0) {
			hwicodec_log(h, C_LOG_ERROR, "tlb yaddr:%p, size:%d failed\n", pplane->caddr, psize->csize);
			goto err_hwicodec_fenc_c_tlb;
		}

		ppool->elem[i % C_VB_NUM_MAX] = e;
		if (ppool->num >= C_VB_NUM_MAX) {
			ppool->num = C_VB_NUM_MAX;
		} else {
			ppool->num++;
		}
	}

	return 0;

err_hwicodec_fenc_y_tlb:
err_hwicodec_fenc_c_tlb:
	return -1;
}

void hwicodec_pf_deinit_bpool(hwicodec_t *h)
{
	h->param.ckfree(h->param.index, (void *)h->soc.bpool.buf_base_v);
}

inline int convert_csp_to_vpu_mode(int i_csp)
{
	switch (i_csp) {
	case C_CSP_T420:
		return HWICODEC_TILE_MODE;
	case C_CSP_I420:
	case C_CSP_NV12:
		return HWICODEC_NV12_MODE;
	case C_CSP_NV21:
		return HWICODEC_NV21_MODE;
	default:
		return HWICODEC_UNSUPPORT_MODE;
	}

	return HWICODEC_UNSUPPORT_MODE;
}

int hwicodec_pf_request_vbinfo(hwicodec_t *h, hwicodec_vbinfo_t **vbinfo, int *vbnum)
{
	*vbinfo = h->soc.bpool.vbinfo;
	*vbnum = h->soc.bpool.vb_num;

	return 0;
}

void hwicodec_pf_release_vbinfo(hwicodec_t *h, hwicodec_vbinfo_t *vbinfo)
{
}
